//
//  IapSDK.swift
//  Game105Client-mobile
//
//  Created by Developer001 on 2025/3/26.
//

import Foundation
import StoreKit

@objc class IapSDK : NSObject, SDKDelegate, SKProductsRequestDelegate, SKPaymentTransactionObserver {
    
    
    // 静态变量持有单例实例
    @MainActor
    static var instance: IapSDK?
    
    var viewController: UIViewController?
    
    @MainActor
    @objc func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        print("@IapSDK launched")
        IapSDK.instance = self
        if let window = application.delegate?.window {
            viewController = window?.rootViewController
        }
        JsbSDK.onMsg("IapSDK.initialize", handler: self.initialize)
        JsbSDK.onMsg("IapSDK.purchase", handler: self.purchase)
        JsbSDK.onMsg("IapSDK.restorePurchase", handler: self.restorePurchase)
        JsbSDK.onMsg("IapSDK.requestProductInfos", handler: self.requestProductInfos)
        return true
    }
    
    func initialize(args: String?) {
        print("@initialize", args as Any)
        SKPaymentQueue.default().add(self)
    }
    
    var purchaseProductId: String?
    
    func purchase(args:String?) {
        print("@purchase", args as Any)
        if let jsonData = args?.data(using: .utf8) {
            do {
                if let json = try JSONSerialization.jsonObject(with: jsonData, options: []) as? [String: Any] {
                    let productId = json["productId"] as? String
                    print("@productId is ", productId as Any)
                    purchaseProductId = productId;
                    requestProductInfo(productIdentifier: productId!)
                }
            } catch {
                print("Error parsing JSON: \(error)")
            }
        }
    }
    
    func restorePurchase(args: String?) {
        print("@restorePurchase", args as Any)
        SKPaymentQueue.default().restoreCompletedTransactions();
    }
    
    func requestProductInfo(productIdentifier: String) {
        let productIdentifiers: Set<String> = [productIdentifier]
        let productsRequest = SKProductsRequest(productIdentifiers: productIdentifiers)
        productsRequest.delegate = self
        productsRequest.start()
    }
    
    func requestProductInfos(args: String?) {
        print("@ ", args as Any)
        if let jsonData = args?.data(using: .utf8) {
            do {
                if let json = try JSONSerialization.jsonObject(with: jsonData, options: []) as? [String: Any],
                    let productIds = json["productIds"] as? [String] {
                    let productIdentifiers: Set<String> = Set(productIds)
                    let productsRequest = SKProductsRequest(productIdentifiers: productIdentifiers)
                    productsRequest.delegate = self
                    productsRequest.start()
                }
            } catch {
                print("Error parsing JSON: \(error)")
            }
        }
    }
    
    func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {
        print("@productsRequest", response.products)
        var purchaseProduct: SKProduct? = nil
        var productsDictionary: [String: [String: Any]] = [:]
        for product in response.products {
            // 展示产品信息给用户
            print("Product title: \(product.productIdentifier) \(product.price) \(product.localizedTitle)")
            // 创建产品字典
            let productInfo: [String: Any] = [
                "product_id": product.productIdentifier,
                "price": product.price,
                "localizedTitle": product.localizedTitle
            ]
            // 将产品信息添加到数组中
            productsDictionary[product.productIdentifier] = productInfo
            if purchaseProductId == product.productIdentifier {
                purchaseProduct = product
            }
        }
        
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
            JsbSDK.sendMsg("IapSDKManager.productsResponse", args: productsDictionary)
        }
        
        if purchaseProduct != nil {
            let product = purchaseProduct
            // 用户购买产品
            if SKPaymentQueue.canMakePayments() {
                let mutablePayment = SKMutablePayment(product: product!)
                SKPaymentQueue.default().add(mutablePayment)
                DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
                    JsbSDK.sendMsg("IapSDKManager.canMake", args: ["productId": product!.productIdentifier])
                }
            } else {
                print("@处理用户设备无法进行购买")
                DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
                    JsbSDK.sendMsg("IapSDKManager.onFailed", args: ["reason": "device"])
                }
            }
            purchaseProductId = nil
        }
    }
    
    func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
        print("@paymentQueue", transactions)
        for transaction in transactions {
            switch transaction.transactionState {
            case .purchased:
                
                // Get the receipt if it's available.
                if let appStoreReceiptURL = Bundle.main.appStoreReceiptURL, FileManager.default.fileExists(atPath: appStoreReceiptURL.path) {
                    do {
                        let receiptData = try Data(contentsOf: appStoreReceiptURL, options: .alwaysMapped)
                        print("@receiptData", receiptData)
                        let receiptString = receiptData.base64EncodedString(options: [])
                        print("@receiptString", receiptString)
                        
                        JsbSDK.sendMsg("IapSDKManager.onPurchased", args: [
                            "id": transaction.transactionIdentifier as Any,
                            "productId": transaction.payment.productIdentifier, 
                            "receipt": receiptString
                        ]);
                        
                        SKPaymentQueue.default().finishTransaction(transaction)
                    } catch {
                        let reason = "Couldn't read receipt data with error: " + error.localizedDescription
                        print(reason)
                        JsbSDK.sendMsg("IapSDKManager.onFailed", args: ["reason": reason, "productId": transaction.payment.productIdentifier])
                    }
                } else {
                    JsbSDK.sendMsg("IapSDKManager.onFailed", args: ["reason": "no appStoreReceiptURL path", "productId": transaction.payment.productIdentifier])
                }
            case .failed:
                SKPaymentQueue.default().finishTransaction(transaction)
                if let error = transaction.error {
                    let reason = error.localizedDescription
                    JsbSDK.sendMsg("IapSDKManager.onFailed", args: ["reason": reason, "productId": transaction.payment.productIdentifier])
                } else {
                    JsbSDK.sendMsg("IapSDKManager.onFailed", args: ["reason": "Unknown error", "productId": transaction.payment.productIdentifier])
                }
            case .restored:
                SKPaymentQueue.default().finishTransaction(transaction)
                JsbSDK.sendMsg("IapSDKManager.onRestored", args: ["productId": transaction.payment.productIdentifier])
            default:
                break
            }
        }
    }
    
}
